package run;

import lsieun.utils.ContainerUtils;
import lsieun.utils.FileUtils;
import lsieun.utils.JarUtils;
import lsieun.utils.NameUtils;
import lsieun.visitor.PatchTransformVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;

import java.io.File;
import java.lang.instrument.ClassFileTransformer;
import java.util.List;

public class B_Patch_Transform_Method {
    public static void main(String[] args) {
        // (1) 备份原来的Jar包
        String jarPath = PathManager.backUpJar();

        // (2) 过滤出真正关心的部分
        Class<?> clazz = ClassFileTransformer.class;
        List<String> jarItems = A_Find_ClassFileTransformer.getJarItems(jarPath, clazz);

        // (3) 更新Jar包: transform method
        String outputDir = PathManager.getOutputPath();
        for (String item : jarItems) {
            byte[] bytes = JarUtils.readClass(jarPath, item);
            if (bytes == null) continue;
            ClassReader cr = new ClassReader(bytes);

            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            PatchTransformVisitor cv = new PatchTransformVisitor(cw);
            cr.accept(cv, 0);

            byte[] newBytes = cw.toByteArray();
            String filepath = outputDir + File.separator + item;
            FileUtils.writeBytes(filepath, newBytes);
            JarUtils.updateJar(jarPath, item, filepath);
            System.out.println("Update Jar: " + item + " ---> " + filepath);
        }

        // (4) 更新Jar包: ContainerUtils
        {
            String className = ContainerUtils.class.getName();
            String internalName = NameUtils.toInternalName(className);
            String jarItem = NameUtils.toJarItemName(internalName);

            String filepath = FileUtils.getFilePath(jarItem);
            JarUtils.updateJar(jarPath, jarItem, filepath);
            System.out.println("Update Jar: " + jarItem + " ---> " + filepath);
        }

        // (5) javaagent
        String vmOptions = String.format("-javaagent:%s", jarPath.replace(File.separatorChar, '/'));
        System.out.println(vmOptions);
    }




}
